using System.Collections.Generic;

namespace Universe.Farm.Service
{
    class HealthStamped
    {
        public TimeStamp Stamp;
        public HealthInfo Info;

        public HealthStamped(TimeStamp stamp, HealthInfo info)
        {
            Stamp = stamp;
            Info = info;
        }
    }

    class HealthCollection : Dictionary<string, Dictionary<string, HealthStamped>>, IHealthCollection
    {
        public IList<HealthInfo> GetServices(ServicesScope scope)
        {
            List<HealthInfo> ret = new List<HealthInfo>();
            if (scope.IsFullScope)
                ret.AddRange(GetAllServices());

            else
            {
                foreach (ServicesScope.Item item in scope.Items)
                {
                    List<Dictionary<string, HealthStamped>> computers = new List<Dictionary<string, HealthStamped>>();
                    if (item.IsAnyComputer)
                        computers.AddRange(this.Values);

                    else
                    {
                        Dictionary<string, HealthStamped> computer;
                        if (this.TryGetValue(item.Computer, out computer))
                            computers.Add(computer);
                    }

                    foreach (Dictionary<string, HealthStamped> computer in computers)
                    {
                        if (item.IsAnyService)
                        {
                            foreach (HealthStamped healthStamped in computer.Values)
                            {
                                ret.Add(healthStamped.Info);
                            }
                        }

                        else
                        {
                            HealthStamped healthInfo;
                            if (computer.TryGetValue(item.ServiceName, out healthInfo))
                                ret.Add(healthInfo.Info);
                        }
                    }
                }
            }

            return ret;
        }

        public IList<HealthInfo> GetAllServices()
        {
            List<HealthInfo> ret = new List<HealthInfo>();
            lock (this)
            {
                foreach (KeyValuePair<string, Dictionary<string, HealthStamped>> byComputers in this)
                {
                    foreach (KeyValuePair<string, HealthStamped> byServices in byComputers.Value)
                    {
                        ret.Add(byServices.Value.Info);
                    }
                }
            }

            return ret;
        }


    }

    class FarmState
    {
        private ConfigurationContainer _config;
        // private HealthCollection _healthState = new HealthCollection();
        private Dictionary<string, TimeStamp> _Stamps = new Dictionary<string, TimeStamp>();
        // private List<DeliveryAgent> _DeliveryStations = new List<DeliveryAgent>();
        private List<NetListenerAgent> _NetListeners = new List<NetListenerAgent>();
        private List<ServiceListenerAgent> _ServiceListeners = new List<ServiceListenerAgent>();

        public HealthCollection HealthState
        {
            get
            {
                return (HealthCollection) _config.ResolveRequired<IHealthCollection>();
            }
        }

        public FarmState(ConfigurationContainer config)
        {
            _config = config;
        }

        public List<DeliveryAgent> DeliveryStations
        {
            get { return _config.ResolveRequired<List<DeliveryAgent>>(); }
        }

        public List<NetListenerAgent> NetListeners
        {
            get { return _NetListeners; }
        }

        public List<ServiceListenerAgent> ServiceListeners
        {
            get { return _ServiceListeners; }
        }


        public Dictionary<string, TimeStamp> Stamps
        {
            get { return _Stamps; }
        }

        public CommunicationParameters CommunicationParameters
        {
            get { return _config.ResolveRequired<CommunicationParameters>(); }
        }


        public IEnumerable<ServiceListenerConfiguration> ServiceListenerConfigList
        {
            get { return _config.ResolveRequired<IEnumerable<ServiceListenerConfiguration>>(); }
        }


        public ConfigurationContainer Config
        {
            get { return _config; }
        }
    }
}
